package com.wwinsoft.framework.dao.security;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.hibernate.Query;
import org.springframework.stereotype.Component;

import com.google.common.collect.Lists;
import com.wwinsoft.framework.entity.security.Authority;
import com.wwinsoft.modules.orm.hibernate.HibernateDao;
import com.wwinsoft.modules.utils.reflection.ConvertUtils;

/**
 * 授权对象的泛型DAO.
 *
 * @author calvin
 */
@Component
public class AuthorityDao extends HibernateDao<Authority, Long> {

    private final static String SELECT_CHILDREN_SQL = "select getAuthorityChildList(:parentId)";
    private final static String DELETE_CHILDREN_SQL = "delete from acct_authority where FIND_IN_SET(id,:ids)";
    private final static String SELECT_PARENT_SQL = "select getAuthorityParentList(:childrenIds)";


    public int deleteAllChildrenBySQL(Serializable id) {
        String children = findChildrenByFunc(id);
        Map paraMap = new HashMap();
        paraMap.put("ids", children);
        Query sqlQuery = this.createSQLQuery(DELETE_CHILDREN_SQL, paraMap);
        return sqlQuery.executeUpdate();
    }

    private String findChildrenByFunc(Serializable id) {
        Map paraMap = new HashMap();
        paraMap.put("parentId", id);
        Query sqlQuery = this.createSQLQuery(SELECT_CHILDREN_SQL, paraMap);
        String idList = (String) sqlQuery.uniqueResult();
        return idList;
    }

    private String findParentsByFunc(String children) {
        Map paraMap = new HashMap();
        paraMap.put("childrenIds", children);
        Query sqlQuery = this.createSQLQuery(SELECT_PARENT_SQL, paraMap);
        String idList = (String) sqlQuery.uniqueResult();
        return idList;
    }

    @SuppressWarnings("unchecked")
    public Collection<Long> getParentsByChildren(List<Long> children){
        String childrenStr = StringUtils.join(children, ",");
        String parentsStr = findParentsByFunc(childrenStr);
        Set<Long> parentsList = ConvertUtils.convertSeparatorStringToSet(parentsStr, ",", Long.class);
        for (Iterator<Long> iterator = parentsList.iterator(); iterator.hasNext(); ) {
            Long parent = iterator.next();
            if(children.contains(parent)){
                iterator.remove();
            }
        }
        return parentsList;
    }

}
